/*
ont-space - The ontology-based resource metadata repository
Copyright (c) 2006-2008, Information Eng. Research Unit - Univ. of Alcalá
http://www.cc.uah.es/ie
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at your option)
any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package org.ontspace.util.translator.lom2owl.owl;

import org.ieee.ltsc.lom.LOM;
import org.ieee.ltsc.lom.LOMUtil;
import org.ieee.ltsc.lom.LOM.Classification.TaxonPath.*;

import java.io.*;
import com.hp.hpl.jena.ontology.*;
import com.hp.hpl.jena.rdf.model.RDFNode;

/**
 * 
 * Translates a LOM classification element to its representation in OWL. 
 */
public class CL2CLTranslator extends ElementTranslatorImpl {

    private String category =
            new String();
    private String attributeName =
            new String();
    private String element =
            new String();

    /** Creates a new instance of CL2CLTranslator */
    public CL2CLTranslator(String elementCategory, String elementElement,
            String elementAttribute) {

        this.category =
                elementCategory;
        this.attributeName =
                elementAttribute;
        this.element =
                elementElement;
    }

    /**
     * 
     * Translates a LOM classification element to its representation in OWL. 
     * @param lom The metadata record
     * @param ont The ontology
     * @param inst The instance of learning Object
     * @param nsName The namespace
     * @param errorWriter The error file
     */
    public void apply(LOM lom, OntModel ont, Individual inst, String nsName,
            PrintWriter errorWriter) {

        OntClass classClassification =
                ont.getOntClass(nsName +
                "#lomClassification");
        OntClass langStringClass =
                ont.getOntClass(nsName + "#langString");
        OntClass singleLangStringClass =
                ont.getOntClass(nsName +
                "#singleLangString");
        OntClass taxonClass =
                ont.getOntClass(nsName + "#lomTaxon");

        ObjectProperty includeLangStringProperty =
                ont.getObjectProperty(nsName + "#includesSingleLangString");
        DatatypeProperty hasValueProperty =
                ont.getDatatypeProperty(nsName +
                "#hasValue");
        DatatypeProperty inLanguageProperty =
                ont.getDatatypeProperty(nsName +
                "#inLanguage");
        DatatypeProperty taxonIdProperty =
                ont.getDatatypeProperty(nsName +
                "#taxonId");
        DatatypeProperty purposeProperty =
                ont.getDatatypeProperty(nsName +
                "#classificationPurpose");
        ObjectProperty taxonEntryProperty =
                ont.getObjectProperty(nsName +
                "#taxonEntry");
        OntClass classTaxonPath =
                ont.getOntClass(nsName + "#lomTaxonPath");
        ObjectProperty classificationTaxonProperty =
                ont.getObjectProperty(nsName + "#classificationTaxon");
        ObjectProperty descriptionProperty =
                ont.getObjectProperty(nsName +
                "#taxonDescription");
        ObjectProperty keywordProperty =
                ont.getObjectProperty(nsName +
                "#classificationKeyword");
        ObjectProperty classificationProperty =
                ont.getObjectProperty(nsName +
                "#hasClassification");
        ObjectProperty classificationTaxonPathProperty =
                ont.getObjectProperty(nsName + "#classificationTaxonPath");
        ObjectProperty classificationSourceProperty =
                ont.getObjectProperty(nsName + "#classificationSource");

        String instance =
                null;

        int i =
                0;

        while (LOMUtil.getClassification(lom, i) != null) {
            instance =
                    "#classification" +
                    inst.getLocalName() + "-" + String.valueOf(i);
            Individual instanceClassification =
                    ont.createIndividual(nsName +
                    instance, classClassification);

            //9.1 purpose                                      

            String purposeLOM =
                    LOMUtil.getValue(LOMUtil.getClassificationPurpose(lom, i));
            if (purposeLOM != null) {
                RDFNode purposeValue =
                        ont.createTypedLiteral(purposeLOM);
                instanceClassification.setPropertyValue(purposeProperty,
                        purposeValue);
            } else {
                String log =
                        "The Purpose field of Classification category must contain a value";
                errorWriter.println(log);
            }
            //9.2 taxon path
            int j =
                    0;

            while (LOMUtil.getClassificationTaxonPath(lom, i, j) != null) {
                instance =
                        "#tPathC" +
                        inst.getLocalName() + "-" + String.valueOf(j);

                Individual instanceTaxonPath =
                        ont.createIndividual(nsName +
                        instance, classTaxonPath);

                int g =
                        0;
                if (LOMUtil.getClassificationTaxonPathSource(lom, i, j) != null) {
                    instance =
                            "#lsTPS" +
                            inst.getLocalName() + "-" + String.valueOf(j);
                    Individual langInstance =
                            ont.createIndividual(nsName +
                            instance, langStringClass);

                    while (LOMUtil.getString(LOMUtil.getClassificationTaxonPathSource(lom,
                            i, j), g) != null) {
                        String sourceLOM =
                                LOMUtil.getString(LOMUtil.getClassificationTaxonPathSource(lom,
                                i, j), g);
                        String languageLOM =
                                LOMUtil.getLanguage(LOMUtil.getClassificationTaxonPathSource(lom,
                                i, j), g);

                        instance =
                                "slsTPS" +
                                inst.getLocalName() + "-" + String.valueOf(g);
                        Individual singleInstance =
                                ont.createIndividual(nsName + instance,
                                singleLangStringClass);

                        if (sourceLOM != null) {
                            RDFNode sourceValue =
                                    ont.createTypedLiteral(sourceLOM);
                            singleInstance.setPropertyValue(hasValueProperty,
                                    sourceValue);
                        }
                        if (languageLOM != null) {
                            RDFNode languageValue =
                                    ont.createTypedLiteral(languageLOM);
                            singleInstance.setPropertyValue(inLanguageProperty,
                                    languageValue);
                        }
                        langInstance.addProperty(includeLangStringProperty,
                                singleInstance);
                        g++;
                    }
                    instanceTaxonPath.setPropertyValue(classificationSourceProperty,
                            langInstance);
                } else {
                    String log =
                            "The Taxon Path Source field of Classification category must contain a value";
                    errorWriter.println(log);
                }
                int k =
                        0;

                //create the taxon instance

                while (LOMUtil.getClassificationTaxonPathTaxon(lom, i, j, k) !=
                        null) {
                    instance =
                            "taxonC" +
                            inst.getLocalName() + "-" + String.valueOf(k);
                    Individual instanceTaxon =
                            ont.createIndividual(nsName +
                            instance, taxonClass);
                    String taxonIdLOM =
                            LOMUtil.getString(LOMUtil.getClassificationTaxonPathTaxonId(lom,
                            i, j, k));
                    if (taxonIdLOM != null) {
                        RDFNode taxonIdValue =
                                ont.createTypedLiteral(taxonIdLOM);
                        instanceTaxon.setPropertyValue(taxonIdProperty,
                                taxonIdValue);
                    }
                    instance =
                            "lsTEntryC" +
                            inst.getLocalName() + "-" + String.valueOf(k);

                    Individual langInstance1 =
                            ont.createIndividual(nsName +
                            instance, langStringClass);

                    int p =
                            0;

                    while (LOMUtil.getString(LOMUtil.getClassificationTaxonPathTaxonEntry(lom,
                            i, j, k), p) != null) {
                        String taxonLOM =
                                LOMUtil.getString(LOMUtil.getClassificationTaxonPathTaxonEntry(lom,
                                i, j, k), p);
                        String languageLOM =
                                LOMUtil.getLanguage(LOMUtil.getClassificationTaxonPathTaxonEntry(lom,
                                i, j, k), p);

                        instance =
                                "slsTEntryC" +
                                inst.getLocalName() + "-" + String.valueOf(p);

                        Individual singleInstance =
                                ont.createIndividual(nsName + instance,
                                singleLangStringClass);
                        if (taxonLOM != null) {
                            RDFNode taxonValue =
                                    ont.createTypedLiteral(taxonLOM);
                            singleInstance.setPropertyValue(hasValueProperty,
                                    taxonValue);
                        } else {
                            String log =
                                    "The TaxonEntry field of Classification category must contain a value";
                            errorWriter.println(log);
                        }
                        if (languageLOM != null) {
                            RDFNode languageValue =
                                    ont.createTypedLiteral(languageLOM);
                            singleInstance.setPropertyValue(inLanguageProperty,
                                    languageValue);
                        } else {
                            String log =
                                    "The Language field of TaxonEntry in the Classification category must contain a value";
                            errorWriter.println(log);
                        }
                        langInstance1.addProperty(includeLangStringProperty,
                                singleInstance);
                        p++;

                    }
                    instanceTaxon.setPropertyValue(taxonEntryProperty,
                            langInstance1);
                    instanceTaxonPath.addProperty(classificationTaxonProperty,
                            instanceTaxon);
                    k++;
                }


                j++;
                instanceClassification.addProperty(classificationTaxonPathProperty,
                        instanceTaxonPath);
            }

            //9.3 description                
            if (LOMUtil.getClassificationDescription(lom, i) != null) {
                int t =
                        0;

                instance =
                        "lsDescrC" +
                        inst.getLocalName() + "-" + String.valueOf(i);

                Individual langInstance2 =
                        ont.createIndividual(nsName +
                        instance, langStringClass);

                while (LOMUtil.getString(LOMUtil.getClassificationDescription(lom,
                        i), t) != null) {

                    String descriptionLOM =
                            LOMUtil.getString(LOMUtil.getClassificationDescription(lom,
                            i), t);
                    String languageLOM =
                            LOMUtil.getLanguage(LOMUtil.getClassificationDescription(lom,
                            i), t);

                    instance =
                            "#slsDescrC" +
                            inst.getLocalName() + "-" + String.valueOf(t);

                    Individual singleInstance =
                            ont.createIndividual(nsName +
                            instance, singleLangStringClass);
                    if (descriptionLOM != null) {
                        RDFNode descriptionValue =
                                ont.createTypedLiteral(descriptionLOM);
                        singleInstance.setPropertyValue(hasValueProperty,
                                descriptionValue);
                    } else {
                        String log =
                                "The Description field of the Classification category must contain a value";
                        errorWriter.println(log);
                    }
                    if (languageLOM != null) {
                        RDFNode languageValue =
                                ont.createTypedLiteral(languageLOM);
                        singleInstance.setPropertyValue(inLanguageProperty,
                                languageValue);
                    } else {
                        String log =
                                "The Language field of Description in the Classification category must contain a value";
                        errorWriter.println(log);
                    }
                    t++;
                    langInstance2.addProperty(includeLangStringProperty,
                            singleInstance);
                }
                instanceClassification.setPropertyValue(descriptionProperty,
                        langInstance2);
            }
            //9.4 keyword
            int n =
                    0;
            int z =
                    0;

            while (LOMUtil.getClassificationKeyword(lom, i, n) != null) {

                instance =
                        "#lsKeyC" + inst.getLocalName() + "-" +
                        String.valueOf(n);

                Individual langInstance3 =
                        ont.createIndividual(nsName +
                        instance, langStringClass);
                z =
                        0;
                while (LOMUtil.getString(LOMUtil.getClassificationKeyword(lom, i,
                        n), z) != null) {
                    String keywordLOM =
                            LOMUtil.getString(LOMUtil.getClassificationKeyword(lom,
                            i, n), z);
                    String languageLOM =
                            LOMUtil.getLanguage(LOMUtil.getClassificationKeyword(lom,
                            i, n), z);

                    instance =
                            "slsKeyC" +
                            inst.getLocalName() + "-" + String.valueOf(z);

                    Individual singleInstance =
                            ont.createIndividual(nsName +
                            instance, singleLangStringClass);
                    if (keywordLOM != null) {
                        RDFNode keywordValue =
                                ont.createTypedLiteral(keywordLOM);
                        singleInstance.setPropertyValue(hasValueProperty,
                                keywordValue);
                    } else {
                        String log =
                                "The Keyword field of Classification category must contain a value";
                        errorWriter.println(log);
                    }
                    if (languageLOM != null) {
                        RDFNode languageValue =
                                ont.createTypedLiteral(languageLOM);
                        singleInstance.setPropertyValue(inLanguageProperty,
                                languageValue);
                    } else {
                        String log =
                                "The Language field of Kewyord in the Classification category must contain a value";
                        errorWriter.println(log);
                    }
                    z++;
                    langInstance3.addProperty(includeLangStringProperty,
                            singleInstance);
                }
                instanceClassification.addProperty(keywordProperty,
                        langInstance3);
                n++;
            }


            i++;

            inst.addProperty(classificationProperty, instanceClassification);
        } //while           

    }
}
